from multiprocessing import  Queue, Value, Lock
import ctypes,os,re,time,json,requests,base64,pytesseract,matplotlib
matplotlib.use('Agg')  
from datetime import datetime, timedelta
from threading import Thread
from PIL import Image
from werkzeug.utils import secure_filename
from io import BytesIO
import numpy as np
import matplotlib.pyplot as plt

from flask import Flask, request, jsonify,current_app, render_template
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
CORS(app) #跨域使用

UPLOAD_FOLDER = 'static/uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# 确保上传文件夹存在
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

api_base_url = 'http://127.0.0.1:7861'

api="/chat/kb_chat"
url = f"{api_base_url}{api}"
max_history=2  #最多向AI输入的历史记录条数

Info,Worning,Error,Fatal=0,1,2,3#正常，警告，错误，致命错误
def print_log(level,content): #日志打印
    current_time = datetime.now()
    formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")

    log_str=['Info',
             'Worning',
             'Error',
             'Error']
    log_out=f"[{log_str[level]} {formatted_time}]{content}\r\n"
    with open("log.txt", "a",encoding="utf-8") as file:
        file.write(log_out)
        print(log_out)

class API_data:
    headers = {'accept': 'application/json','Content-Type': 'application/json',"X-Stream-Priority": "high",    # 服务端流优先级
    "X-Chunk-Size": "1024",         
    "X-Response-Speed": "turbo" }

    #headers = {'accept': 'application/json','Content-Type': 'application/json'}
    is_ready = False

    data = {
    "query": "",
    "mode": "local_kb",
    "kb_name": "math",
    "top_k": 5,
    "score_threshold": 1.25,
    "history": [],
    "stream": True,
    "model": "qwen2.5-instruct",
    "temperature": 0.5,
    "max_tokens": 0,
    "prompt_name": "default",
    "return_direct": False
    }

    def set_history(self,history):
        self.data['history']=history
        
    def set_ready(self,statu):
        self.is_ready=statu    

api_data=API_data()
question=""
queue = Queue()
history_queue =Queue()
simple_question=Queue()
lock = Lock()
is_wait = Value(ctypes.c_bool,False)#这个用来等待
last_id= Value(ctypes.c_int)

def add_new_history(history,is_new):
    
    with lock:
        history.append(history_queue.get()) 

    if  is_new == 'false':
        history=history[:-3]

    with lock:
        history.append(history_queue.get()) 
        history.append(history_queue.get()) 
    return history

def add_simple_question(question,history,f):
    
    #api_data.data['history']=history
    if f == 0:
        simple_question.put([])
        return
    api_data.data['history']=history
    api_data.data['query']=f"根据: {question}，生成三个类似问题，不需要任何形式的解答与解释，也不要给出任何多余回答,每个问题前加上编号，编号与问题在同一行"
    print_log(Info,'正在生成相关问题')
    as_content=""
    response = requests.post(url, headers=API_data.headers, json=API_data.data, stream=False)
    for line in response.iter_lines(decode_unicode=True):  
        try:
            line = line.strip()
            if line.startswith("data: {"):
                
                json_str = line.split("data: ", 1)[1]
                data_dict = json.loads(json_str)
                content = data_dict.get("choices", [{}])[0].get("delta", {}).get("content", "")

                if content:
                    as_content+=content              
                    
        except json.JSONDecodeError as e:
            print_log(Fatal,f"debug: JSON解析失败: {e}")   
            return 405

    result = as_content.split('\n')
    ans =[]
    for rest in result:
        if rest and rest[0].isnumeric():
            rest.replace('?', '')
            rest.replace('？', '')
            rest.replace(':', '=')
            rest=rest[3:]
            ans.append(rest)
    print_log(Info,f'生成相关问题如下：{ans}')
    with lock:
        simple_question.put([ans])
    return 200

#进程1：流式获取AI回答并写入队列
def process1(history,output_queue,question,history_queue):
    with app.app_context():

        st_time=time.time()
        print_log(Info,"AI运行成功")
        is_frist=True
        api_history=[]
        if history:
            for historys in history:
                if historys.get('role') != 'title':
                    api_history.append(historys)

        if api_history:
            api_data.data['history']=api_history[-(max_history*2):] #保留最后五条历史记录

        history_queue.put({"role":"user","content":question})    
        queue.put([{'status': 'continue',"role":"user","content":question}])
        api_data.data["query"]=question
        
        print_log(Info,f"历史记录加载成功")
        print_log(Info,f"提问问题加载成功")
        
        response = requests.post(url, headers=api_data.headers, json=api_data.data, stream=True)

        ed=time.time()
        print_log(Info,f"AI思考开始时间{(ed-st_time)}")
        as_content=""
        is_search=True

        for line in response.iter_lines(chunk_size=1,decode_unicode=True):          
            try:
                line = line.strip()
                
                if line.startswith("data: {"):
                    if is_search == True:
                        is_search =False
                        json_str = line.split("data: ", 1)[1]
                        data_dicts = json.loads(json_str)
                        data_dict=data_dicts.get("docs")
                        output_queue.put([{"status":'continue',"content":data_dict,"role": "title"}])
                        history_queue.put({"role":"title","content":data_dict})  

                    else:
                       
                        json_str = line.split("data: ", 1)[1]
                        data_dict = json.loads(json_str)
                        content = data_dict.get("choices", [{}])[0].get("delta", {}).get("content", "")

                        if content:
                            as_content+=content
                            if is_frist == True:  
                                is_frist=False                      
                                ed=time.time() 
                                print_log(Info,f"AI开始回答时间：{(ed-st_time)}")

                            contents=[{"status":'continue',"content":content,"role": "assistant"}]
                            output_queue.put(contents)  # 将内容推送到队列
            except json.JSONDecodeError as e:
                print_log(Fatal,f"debug: JSON解析失败: {e}")        
        


        abc_pattern = r"a\s*=\s*(-?\d+),\s*b\s*=\s*(-?\d+),\s*c\s*=\s*(-?\d+)"
        abc_match = re.search(abc_pattern, as_content)
        f=1
        if abc_match:
            abc=[int(abc_match.group(1)), int(abc_match.group(2)), int(abc_match.group(3))]
            #print(abc)
            #output_queue.put([{"status":'continue',"content":create_plot(abc),"role": "image","fomat":"png","isLoading":True,"isError":False,"altText":"本图片由AI生成"}])
            path=create_plot(abc)
            if path :
                output_queue.put([{"status":'continue',"content":path,"role": "image"}])
            f=0
        ed_time=time.time()
        if f==1:
            output_queue.put([{"status":'stop',"content":"","role": "assistant"}])  # 发送结束信号
            
        print_log(Info,f"AI回答结束,回答用时{ed_time-st_time}") 
        history_queue.put({"role": "assistant",'content':as_content}) 
        print_log(Info,f"AI最终回答内容：{as_content}")
        res=add_simple_question(question,api_data.data['history'],1)  
        if res == 200:
            print_log(Info,'相关问题生成成功')
        else:
            print_log(Fatal,'相关问题生成失败')

def process2(id,is_new,username,history): 
    time.sleep(3)
    with app.app_context():
        if id:
            print_log(Info,f'id是：{id} 开始专业版历史记录添加') 
            history=add_new_history(history,is_new)
            change_history(history,id)
            print_log(Info,f'id是：{id} 专业版历史记录添加完成') 
        else:
            print_log(Info,f'id为空 开始精简版历史记录添加')
            new_history=[]
            new_history=add_new_history(new_history,'true')  
            add_simplify_history(username,new_history)
            print_log(Info,f'id为空 精简版历史记录添加完成')

        


def clear(queue):
    with lock:
        while not queue.empty():
            print_log(Info,f'队列清空中{queue.get()}')

        while not history_queue.empty():
            print_log(Info,f'队列清空中{history_queue.get()}')
            
        while not simple_question.empty():
            print_log(Info,f'队列清空中{simple_question.get()}')
    print_log(Info,f'队列清空完毕')


headers = {
    "Content-Type": "application/json",  # 确保与Postman一致
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",  # 模拟浏览器
    "Authorization": "",  # 必填项（根据API要求修改）
    "X-API-Key": "",  # 根据API文档添加
    "Accept": "application/json",  # 声明可接受的响应类型
    # 其他Postman中存在的Header字段（如Referer、Accept-Language等）
    }
def to_get(url,data):
    with requests.Session() as s:
        s.headers.update(headers)     
        try:
            response = s.get(url, json=data)
            response.raise_for_status()
            
            print_log(Info,"请求成功！")
            print_log(Info,f"响应内容:, {response.json()}")
            return response
            
        except requests.exceptions.HTTPError as err:
            print_log(Error,f"请求失败，状态码：{err.response.status_code}")
            print_log(Error,f"响应内容:, {err.response.text}")
            return 422
        except Exception as e:
            print_log(Error,f"其他错误:, {str(e)}")
            return 403
def to_post(url,data):

    with requests.Session() as s:
        s.headers.update(headers)     
        try:
            response = s.post(url, json=data)
            response.raise_for_status()
            
            print_log(Info,"请求成功！")
            #print_log(Info,f"响应内容:, {response.json()}")
            return 200
            
        except requests.exceptions.HTTPError as err:
            print_log(Error,f"请求失败，状态码：{err.response.status_code}")
            print_log(Error,f"响应内容:, {err.response.text}")
            return 422
        except Exception as e:
            print_log(Error,f"其他错误:, {str(e)}")
            return 403

def get_VK(request,VKname):
    if request.is_json:
        data = request.get_json()
        return data.get(VKname)
    else:
        return request.form.get(VKname)

@app.route('/add_base',methods=['POST','GET'])
def add_base():
    url = f"{api_base_url}/knowledge_base/create_knowledge_base" 
    
    base_name = get_VK(request,'base_name')

    data={
  "knowledge_base_name": base_name,
  "vector_store_type": "faiss",
  "kb_info": "",
  "embed_model": "bge-large-zh-v1.5"
} 

    res=to_post(url,data)
    if res == 200:
        return '添加成功'
    else:
        return '添加失败'
@app.route('/delete_base',methods=['POST','GET'])
def delete_base():
    url = f"{api_base_url}/knowledge_base/delete_knowledge_base"
    base_name = get_VK(request,'base_name')
    data=base_name
    res=to_post(url,data)
    if res == 200:
        return '删除成功'
    else:
        return '删除失败'

@app.route('/show_base',methods=['POST','GET'])
def show_base():
    url = f"{api_base_url}/knowledge_base/list_knowledge_bases"

    res=to_get(url,None)
    if res :
        return res.json()
    else:
        return '获取失败'
    
@app.route('/change_base_name',methods=['POST','GET'])
def change_base_name():
    base_path = "C:\\Users\\13241\\data\\knowledge_base\\"
    old_name=get_VK(request,'old_name')
    new_name=get_VK(request,'new_name')
    old_folder_name = f'{base_path}{old_name}'
    new_folder_name = f'{base_path}{new_name}'

    try:
        os.rename(old_folder_name, new_folder_name)
        print_log(Info,"文件夹重命名成功！")
        url1=f'{api_base_url}/knowledge_base/recreate_vector_store'
        url2 = f"{api_base_url}/knowledge_base/delete_knowledge_base"
        data1={
        "knowledge_base_name": new_name,
        "allow_empty_kb": True,
        "vs_type": "faiss",
        "embed_model": "bge-large-zh-v1.5",
        "chunk_size": 750,
        "chunk_overlap": 150,
        "zh_title_enhance": False,
        "not_refresh_vs_cache": False
        }
        data2=old_name
        res1,res2 = to_post(url1,data1),to_post(url2,data2)
        if res1 ==200 and res2==200:
            return '修改成功'

    except OSError as e:
        print_log(Error,f"错误: {e}")

    return '修改失败'

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


def create_plot(content):
    # 参数校验
    if len(content) != 3:
        raise ValueError("需要三个系数参数 [a, b, c]")
    
    a, b, c = content[0], content[1], content[2]
    
    if a == 0:
        raise ValueError("系数a不能为0")
    
    # 配置字体（确保系统已安装SimHei字体）
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    
    try:
        # 计算顶点坐标
        vertex_x = -b / (2 * a)
        vertex_y = (4 * a * c - b**2) / (4 * a)
        
        # 生成数据点
        x = np.linspace(vertex_x - 5, vertex_x + 5, 400)
        y = a * x**2 + b * x + c
        
        # 创建新图形对象
        fig = plt.figure(figsize=(8, 6), dpi=100)
        ax = fig.add_subplot(111)
        
        # 绘图逻辑
        ax.plot(x, y, label=f'y = {a}x^2 + {b}x + {c}', color='blue')
        ax.scatter(vertex_x, vertex_y, color='red', zorder=5)
        ax.annotate(f'顶点({vertex_x:.2f}, {vertex_y:.2f})',
                     xy=(vertex_x, vertex_y),
                     xytext=(vertex_x + 0.5, vertex_y + 0.5),
                     arrowprops=dict(arrowstyle="->", color='red'))
        
        ax.set_title("一元二次方程图像")
        ax.set_xlabel("x")
        ax.set_ylabel("y")
        ax.grid(True, linestyle='--', alpha=0.7)
        ax.axhline(0, color='black', linewidth=0.5)
        ax.axvline(0, color='black', linewidth=0.5)
        ax.legend()

        # 转换为Base64
        buffer = BytesIO()
        fig.savefig(buffer, format='png', bbox_inches='tight')
        img_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
        
        return f"data:image/png;base64,{img_base64}"
        
    except Exception as e:
        # 异常时强制关闭图形
        plt.close('all')
        raise  # 重新抛出异常供上层处理
    finally:
        # 确保资源释放
        plt.close('all')
        if 'fig' in locals():
            plt.close(fig)


@app.route('/')
def index():
    return '''
    <!DOCTYPE html>
    <html>
    <body>
        <input type="number" id="a" value="-3">
        <input type="number" id="b" value="-6">
        <input type="number" id="c" value="3">
        <button onclick="loadImage()">生成图像</button>
        <img id="plot" src="" style="max-width: 80%;">
        
        <script>
            function loadImage() {
                const a = document.getElementById('a').value;
                const b = document.getElementById('b').value;
                const c = document.getElementById('c').value;
                
                fetch(`/get_image?a=${a}&b=${b}&c=${c}`)
                    .then(response => response.json())
                    .then(data => {
                        document.getElementById('plot').src = data.image_url;
                    });
            }
            // 初始加载
            loadImage();
        </script>
    </body>
    </html>
    '''
# @app.route('/', methods=['POST','GET']) #测试连接使用
# def hello_world():
#     return 'Hello, World!'

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
   
    # 检查是否有文件被上传
    if 'file' not in request.files:
        print_log(Error,"未选择文件")
        return jsonify({'error': '未选择文件'}), 400
    
    file = request.files['file']
    
    # 检查文件名是否合法
    if file.filename == '':
        print_log(Error,"图片名不合法")
        return jsonify({'error': '图片名不合法'}), 400
    
    if file and allowed_file(file.filename):
        # 安全处理文件名
        filename = secure_filename(file.filename)
        # 保存文件到服务器
        save_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        file.save(save_path)
        
        # 保存信息和文件 URL
        file_url = f"F:/demo2/flask/static/uploads/{filename}"
        pytesseract.pytesseract.tesseract_cmd = r'D:\OCRT\tesseract.exe'
        print_log(Info,"图片上传正确")
        #读取图片并提取文本
        image = Image.open(file_url)
        text = pytesseract.image_to_string(image, lang='chi_sim+eng')  # 中英文混合识别
        print_log(Info,"图片解析正确")
        return jsonify({
            'message': '图片解析正确',
            'text':text
        }), 200
    else:
        return jsonify({'error': '图片类型不允许'}), 400

@app.route('/test_add/<int:day>', methods=['POST','GET'])
def test_add(day):
    content=get_VK(request,'content')
    is_chat=get_VK(request,'is_chat')
    history_name=get_VK(request,'history_name')
    custom_time = datetime.now() - timedelta(day)
    if is_chat == 'yes':
# 创建新历史记录并手动设置时间
        new_history = History(
            
            history_data=[{"role":'user','content':content},{"role": "assistant",'content':'陈腐？操？不！陈，思潮！'}],
            history_name=history_name,
            user_username="admin",
            last_accessed_time=custom_time,  # 手动指定时间   
        )
        return_s='ok1'
    else :
        new_history =HistorySimplify(
            history_data=[{"role":'user','content':content},{"role": "assistant",'content':'陈腐？操？不！陈，思潮！'}],
            history_name=history_name,
            user_username="admin",
            last_accessed_time=custom_time,
            is_collection=False #是否为收藏
        )
        return_s='ok2'
    db.session.add(new_history)
    db.session.commit()
    return return_s

@app.route('/wait', methods=['POST','GET'])
def wait_out():
    with lock:
        is_wait.value=True
    return '暂停成功'

@app.route('/continue', methods=['POST','GET'])   
def ans_agin():
    with lock:
        is_wait.value=False
    return '继续输出'

@app.route('/about', methods=['POST','GET'])
def about():
    
    if is_wait.value == False :
        content=queue.get()
    else: 
        content=[{"role": "assistant", "content": question,"status":"wait"}] 
    return content

@app.route('/submit', methods=['POST','GET'])
def submit():
    t = Thread(target=clear, args=(queue,))
    t.start()
    t.join(timeout=1)
    
    question=get_VK(request,'question')
    username=get_VK(request,'username')
    id=get_VK(request,'id')
    is_new=get_VK(request,'is_new')
    
    if not question:
        print_log(Error,"问题为空")
        return 'false'

    if question[-1]=='\n': #删除末尾\n
        question=question[:-1] 

    print_log(Info,f'提问的问题是：{question}')     
    #question =f'{question}, 不要输出：“根据已知信息无法回答该问题。”'     
    is_wait.value = False 
    history=[]
    if id:
        history=get_data(id)
        
    t1 = Thread(target=process1, args=(history, queue, question,history_queue))
    t1.start()

    t2= Thread(target=process2, args=(id,is_new,username,history))
    t2.start()

    print_log(Info,f"用户提问返回成功")    
    while queue.qsize() < 3:
        f=1
    
    #time.sleep(6)
    return f'true'

@app.route('/get_simple_question', methods=['POST','GET'])
def get_simple_question():
    
    return simple_question.get()

###===============数据库操作===============###

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'  # 使用 SQLite 数据库
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

class History(db.Model):
    __tablename__ = 'history'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    history_data = db.Column(db.JSON, nullable=False)
    history_name = db.Column(db.String(256), nullable=False)
    last_accessed_time = db.Column(
        db.DateTime,
        default=datetime.now,
        onupdate=datetime.now,
        nullable=False
    )
    user_username = db.Column(db.String(80), db.ForeignKey('user.username'), nullable=False)
    user = db.relationship('User', back_populates='histories')

    def __repr__(self):
        return f'<id {self.id}>'

class HistorySimplify(db.Model):
    __tablename__ = 'history_simplify'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    history_data = db.Column(db.JSON, nullable=False)
    history_name = db.Column(db.String(256), nullable=False)
    is_collection= db.Column(db.Boolean, nullable=False) #是否是收藏
    last_accessed_time = db.Column(
        db.DateTime,
        default=datetime.now,
        onupdate=datetime.now,
        nullable=False
    )
    user_username = db.Column(db.String(80), db.ForeignKey('user.username'), nullable=False)
    user = db.relationship('User', back_populates='simplified_histories')

    def __repr__(self):
        return f'<id {self.id}>'

class User(db.Model):
    __tablename__ = 'user'
    username = db.Column(db.String(80), unique=True, primary_key=True)
    password = db.Column(db.String(80), nullable=False)

    histories = db.relationship(
        'History',
        back_populates='user',
        cascade='all, delete-orphan',
        order_by="desc(History.last_accessed_time)"  # 在此处定义排序
    )

    simplified_histories = db.relationship(
        'HistorySimplify',
        back_populates='user',
        cascade='all, delete-orphan',
        order_by="desc(HistorySimplify.last_accessed_time)"
    )

    def __repr__(self):
        return f'<User {self.username}>'

#新建数据库
with app.app_context():
    db.create_all()

@app.route('/get_collect', methods=['POST', 'GET'])
def get_collect():
    username =get_VK(request,'username')

    if username:
        datas  = HistorySimplify.query.filter_by(user_username=username).order_by(HistorySimplify.last_accessed_time.desc()).all()
        history_list=[]
        for data in datas:
            if data.is_collection == True:
                history_list.append({"id":data.id,"name":str(data.history_name),"is_collection":data.is_collection})

        return [history_list]
    else:
        print_log(Worning,"用户名不存在")
        return '用户名不存在'

@app.route('/change_collect', methods=['POST', 'GET'])
def change_collect():
    id=last_id.value
    history = HistorySimplify.query.get(id)
    if history:
        history.is_collection = not history.is_collection
        db.session.commit()

    return 'ok'

@app.route('/change_collect/<int:id>', methods=['POST', 'GET'])
def change_collect2(id):
    history = HistorySimplify.query.get(id)
    if history:
        history.is_collection = not history.is_collection
        db.session.commit()

    return 'ok'

@app.route('/add_history', methods=['POST', 'GET'])
def add_data():
    username =get_VK(request,'username')
    test_name =get_VK(request,'test_name')
    
    new_data = History(
        history_data=[],
        user_username=username,
        history_name=test_name
        )
    
    db.session.add(new_data)
    db.session.commit()
    print_log(Info,"新建历史记录成功")
    return f'{new_data.id}'

@app.route('/get_simplify/<int:id>', methods=['POST','GET'])
def get_data_simplify(id):
    try:
        last_id.value=id
        history = HistorySimplify.query.get(id)
        if history:
            return jsonify({
                "history_data": history.history_data,
                "history_name": history.history_name
            })
        else:
            return jsonify({"error": "History not found"}), 404
    except Exception as e:
        print_log(Error, f"查询失败: {str(e)}")
        return jsonify({"error": "Server error"}), 500
    
@app.route('/get_simplify_list/', methods=['POST','GET'])
def get_simplify():
    username =get_VK(request,'username')

    #print_log(Info,f'用户名是{username}')

    if username:
        datas  = HistorySimplify.query.filter_by(user_username=username).order_by(HistorySimplify.last_accessed_time.desc()).all()
        history_list=[]
        days=[datetime.now() - timedelta(1),datetime.now() - timedelta(2),datetime.now() - timedelta(7),datetime.now() - timedelta(30)]
        c_day=['今天','昨天','七天内','30天内','30天外']
        day=0
        for data in datas:
            if day == 0 or day == 4 or (day<5 and data.last_accessed_time < days[day]):
                history_list.append({"id":-1,"name":c_day[day],"is_collection":data.is_collection})
                day+=1
            history_list.append({"id":data.id,"name":str(data.history_name),"is_collection":data.is_collection})

        return [history_list]
    else:
        print_log(Worning,"用户名不存在")
        return '用户名不存在'

def add_simplify_history(username,history):
    test_name=history[0].get('content')
    test_name=test_name
    new_data =HistorySimplify(
        history_data=history,
        user_username=username,
        history_name=test_name,
        is_collection=False)
    
    db.session.add(new_data)
    db.session.commit()
    last_id.value = new_data.id
    print_log(Info,"新建历史记录成功")

#读取记录
@app.route('/get_history_list/', methods=['POST','GET'])
def get_list():  
    username =get_VK(request,'username')   

    if username:
        datas  = History.query.filter_by(user_username=username).order_by(History.last_accessed_time.desc()).all()
        #datas=History.query.order_by(History.last_accessed_time.desc()).all()
        history_list=[]
        days=[datetime.now() - timedelta(1),datetime.now() - timedelta(2),datetime.now() - timedelta(7),datetime.now() - timedelta(30)]
        c_day=['今天','昨天','七天内','30天内','30天外']
        day=0
        for data in datas:
            if day == 0 or day == 4 or (day<5 and data.last_accessed_time < days[day]):
                history_list.append({"id":-1,"name":c_day[day]})
                day+=1
            history_list.append({"id":data.id,"name":str(data.history_name)})
            
        print_log(Info,"历史记录列表获取成功")
        return [history_list]
    else:
        print_log(Worning,"用户名不存在")
        return '用户名不存在'

@app.route('/get_history/<int:id>', methods=['POST','GET'])
def get_data(id):
    history_id=History.query.get(id)
    history=[]
    if history_id:
        history=history_id.history_data
        print_log(Info,"历史记录获取成功")
        return history
    else:
        print_log(Error,"历史记录id不存在")
        return None

@app.route('/load', methods=['POST', 'GET'])
def load():  
    username =get_VK(request,'username')
    password = get_VK(request,'password')
    if username == None or password == None:
        return '账号或密码为空'

    data = User.query.get(username)
    if not data :
        print_log(Worning,'用户不存在')
        return '用户不存在'
    else:
        if data.password == password :
            print_log(Info,'登录成功')
            return '登录成功'
        else :
            print_log(Worning,'登录失败，密码错误')
            return '登录失败，密码错误'


@app.route('/delete_history/<int:id>', methods=['POST', 'GET'])
def delete_user(id):
    is_simplify = get_VK(request,'is_simplify')

    if is_simplify:
        data = HistorySimplify.query.get(id)
    else:    
        data = History.query.get(id)

    if data:
        db.session.delete(data)
        db.session.commit()
        print_log(Info,"历史记录删除成功")
        return '删除成功'
    print_log(Worning,"历史记录删除失败")
    return '删除失败'

@app.route('/change_history_name/<int:id>', methods=['POST', 'GET'])
def change_history_name(id):
    is_simplify = get_VK(request,'is_simplify')

    if is_simplify:
        data = HistorySimplify.query.get(id)
    else:    
        data = History.query.get(id)

    new_name = get_VK(request,'new_name')

    if data:
        data.history_name=new_name
        db.session.commit()
        print_log(Info,'历史记录名字修改成功')
        return '历史记录名字修改成功'
    
    print_log(Error,'历史记录不存在')
    return '历史记录不存在'

@app.route('/add_user', methods=['POST', 'GET'])
def add_user(): 
    usernameN = get_VK(request,'username')
    passwordN = get_VK(request,'password')

    if not re.match(r'\d', usernameN ) and not re.match(r'[a-zA-Z]', usernameN ):
        print_log(Worning,'账号只允许存在数字和字母')
        return '账号只允许存在数字和字母'
    
    if len(usernameN)>60 or len(passwordN)>60:
        print_log(Worning,'账号或密码不能超过60位')
        return '账号或密码不能超过60位'

    if User.query.get(usernameN):
        print_log(Worning,'该账号已经存在')
        return '该账号已经存在'

    new_data = User(
        username=str(usernameN),
        password=str(passwordN)
        )

    db.session.add(new_data)
    db.session.commit()
    print_log(Info,'账号新建成功')
    return 'new_history.id'     

def change_history(history,id):
    print_log(Info,f"添加的历史记录id是:{id}")
    with current_app.app_context():  # 使用 current_app 获取应用实例
        data = History.query.get(id)
        if data:
            try:
                data.history_data = history
                db.session.commit()
                print_log(Info,'新记录添加成功')
                return '修改成功'
            except Exception as e:
                db.session.rollback()
                print_log(Fatal,f'修改失败: {str(e)}')

                return f'修改失败: {str(e)}'
        else:    
            print_log(Error,'修改失败: 记录不存在')
            return '修改失败: 记录不存在'
    

def warmup_gpu():
    try:
        response = requests.post(url, headers=api_data.headers, json=api_data.data)
        print_log(Info,f"GPU 预热完成，状态码: {response.status_code}")
    except Exception as e:
        print_log(Fatal,f"预热失败: {e}")


if __name__ == "__main__":
    with app.app_context():
        warmup_gpu() 
    
    app.run(debug=True,host='0.0.0.0', port=5000)